/*******************************************************************************
Game.cpp

Notes:
*******************************************************************************/

#include "Game.h"

//	Initialize(int iWidth, int iHeight, std::string strTitle, bool bIsFullscreen)
//		Sets up the window for use in the views
//			iWidth - The width of the display
//			iHeight - The height of the display
//			strTitle - The title of the window
//			bIsFullscreen - Is the game running in fullscreen
bool Game::Initialize(int iWidth, int iHeight, std::string strTitle, bool bIsFullscreen)
{
	// Store the width and height
	m_iWidth = iWidth;
	m_iHeight = iHeight;

	// Create a SFML VideoMode object and initialize it with the width and height given
	sf::VideoMode videoMode(iWidth, iHeight);

	// Create a long integer to hold the window style
	long windowStyle;

	// If the game should run fullscreen...
	if(bIsFullscreen)
	{
		// ... set the style to the Fullscreen style
		windowStyle = sf::Style::Fullscreen;
	}
	else
	{
		// otherwise, set it to a normal window style
		windowStyle = sf::Style::Resize | sf::Style::Close;
	}

	// Create the window using the video mode, title and window style
	m_window.Create(videoMode, strTitle, windowStyle);

	// Return success
	return true;
} // Initialize(int iWidth, int iHeight, std::string strTitle, bool bIsFullscreen)

//	Start(void)
//		Starts the game loop.
int Game::Start(void)
{
	// Load a paddle entity
	EntityResource paddleData;
	paddleData.LoadFromFile("resources/Paddle.txt");
	// Load the computer paddle entity
	EntityResource cpuData;
	cpuData.LoadFromFile("resources/CpuHard.txt");
	// Load a level entity
	EntityResource levelData;
	levelData.LoadFromFile("resources/Level.txt");
	// Load a ball entity
	EntityResource ballData;
	ballData.LoadFromFile("resources/Ball.txt");

	// Get pointers to the entity, controller and view managers
	EntityManager* pEntityMan = EntityManager::GetManager();
	ControllerManager* pControllerMan = ControllerManager::GetManager();
	ViewManager* pViewMan = ViewManager::GetManager();

	// Create the entities and the views
	EntityID paddleID = pEntityMan->CreateEntity(paddleData);
	pViewMan->CreateView(paddleID, paddleData);

	EntityID cpuID = pEntityMan->CreateEntity(cpuData);
	pViewMan->CreateView(cpuID, cpuData);

	EntityID levelID = pEntityMan->CreateEntity(levelData);
	pViewMan->CreateView(levelID, levelData);

	EntityID ballID = pEntityMan->CreateEntity(ballData);
	pViewMan->CreateView(ballID, ballData);

	// Get entity data
	float fPaddleWidth = pEntityMan->GetEntity(paddleID)->GetWidth();
	float fPaddleHeight = pEntityMan->GetEntity(paddleID)->GetHeight();
	float fCpuWidth = pEntityMan->GetEntity(cpuID)->GetWidth();
	float fCpuHeight = pEntityMan->GetEntity(cpuID)->GetHeight();

	float fMapX = pEntityMan->GetEntity(levelID)->GetX();
	float fMapY = pEntityMan->GetEntity(levelID)->GetY();
	float fMapWidth = (float)m_iWidth;
	float fMapHeight = (float)m_iHeight;

	float fBallWidth = pEntityMan->GetEntity(ballID)->GetWidth();
	float fBallHeight = pEntityMan->GetEntity(ballID)->GetHeight();

	// Set the initial position of the entities
	pEntityMan->GetEntity(paddleID)->SetPosition(fMapX + (fPaddleWidth / 2.0f), (fMapY + fMapHeight / 2.0f) - (fPaddleHeight / 2.0f));
	pEntityMan->GetEntity(cpuID)->SetPosition((fMapX + fMapWidth) - (fCpuWidth * 1.5f), (fMapY + fMapHeight / 2.0f) - (fCpuHeight / 2.0f));
	pEntityMan->GetEntity(ballID)->SetPosition((fMapX + fMapWidth / 2.0f) - (fBallWidth / 2.0f), (fMapY + fMapHeight / 2.0f) - (fBallHeight / 2.0f));
	pEntityMan->GetEntity(levelID)->SetSize(fMapWidth, fMapHeight);

	// Create an event and timer object
	sf::Event windowEvent;
	sf::Clock timer;

	// While our window is still open
	while(m_window.IsOpened())
	{
		// While there is an event that needs to be handled
		while(m_window.GetEvent(windowEvent))
		{
			// If the event is the user clicking the close button ...
			if(windowEvent.Type == sf::Event::Closed)
			{
				// ... close the window
				m_window.Close();
			}

			// If the event is a key being pressed, and that key is escape...
			if(windowEvent.Type == sf::Event::KeyPressed &&
				windowEvent.Key.Code == sf::Key::Escape)
			{
				// ... close the window
				m_window.Close();
			}
		}

		// Get the elapsed time since the last frame
		float fElapsed = timer.GetElapsedTime();
		timer.Reset();

		// Update the controllers
		pControllerMan->Update(m_window.GetInput());

		// Clear the window to black
		m_window.Clear();

		// Update the entity manager and render the view manager
		pEntityMan->Update(fElapsed);
		pViewMan->Render(m_window);

		// Display the scene on the window
		m_window.Display();
	}

	// Return success
	return 0;
} // Start(void)